namespace DotNetNuke.UI.WebControls
{
    using DotNetNuke.UI.Design.WebControls;
    using DotNetNuke.UI.Utilities;
    using Microsoft.VisualBasic;
    using Microsoft.VisualBasic.CompilerServices;
    using System;
    using System.Collections;
    using System.Collections.Specialized;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;

    [DefaultProperty("Nodes"), Designer(typeof(DNNTreeDesigner)), ControlBuilder(typeof(DNNTreeBuilder)), ToolboxData("<{0}:DNNTree runat=server></{0}:DNNTree>")]
    public class DnnTree : WebControl, IPostBackEventHandler, IPostBackDataHandler, IClientAPICallbackEventHandler
    {
        private NodeImageCollection m_objImages;
        private TreeNodeCollection m_objNodes;

        public event DNNTreeEventHandler Collapse;

        public event DNNTreeEventHandler Expand;

        public event DNNTreeNodeClickHandler NodeClick;

        public event DNNTreeEventHandler PopulateOnDemand;

        public DnnTree()
        {
            base.PreRender += new EventHandler(this.DnnTree_PreRender);
        }

        private void DnnTree_PreRender(object sender, EventArgs e)
        {
            this.RegisterClientScript();
            this.Page.RegisterRequiresPostBack(this);
            this.UpdateNodes(this.TreeNodes);
            if (!this.IsDownLevel)
            {
                ClientAPI.RegisterClientVariable(this.Page, this.ClientID + "_xml", this.TreeNodes.ToXml(), true);
            }
            else
            {
                this.ViewState["xml"] = this.TreeNodes.ToXml();
                if (ClientAPI.BrowserSupportsFunctionality(ClientAPI.ClientFunctionality.DHTML))
                {
                    ClientAPI.RegisterClientReference(this.Page, ClientAPI.ClientNamespaceReferences.dnn);
                    if (this.SelectedTreeNodes.Count > 0)
                    {
                        ClientAPI.RegisterClientVariable(this.Page, this.ClientID + "_selNode", ((TreeNode) this.SelectedTreeNodes[1]).ToJSON(false), true);
                    }
                }
            }
        }

        public TreeNode FindNode(string strID)
        {
            return this.TreeNodes.FindNode(strID);
        }

        public TreeNode FindNodeByKey(string strKey)
        {
            return this.TreeNodes.FindNodeByKey(strKey);
        }


        public bool LoadPostData(string postDataKey, NameValueCollection postCollection)
        {
            return false;
        }

        protected override void LoadViewState(object state)
        {
            if (state != null)
            {
                object[] objArray = (object[]) state;
                if (objArray[0] != null)
                {
                    base.LoadViewState(RuntimeHelpers.GetObjectValue(objArray[0]));
                }
                if (objArray[1] != null)
                {
                    ((IStateManager) this.ImageList).LoadViewState(RuntimeHelpers.GetObjectValue(objArray[1]));
                }
            }
            if (this.IsDownLevel && (Strings.Len(RuntimeHelpers.GetObjectValue(this.ViewState["xml"])) > 0))
            {
                this.m_objNodes = new TreeNodeCollection(StringType.FromObject(this.ViewState["xml"]), "", this);
            }
        }

        public void LoadXml(string strXml)
        {
            this.m_objNodes = new TreeNodeCollection(strXml, "", this);
        }

        public virtual void OnCollapse(DNNTreeEventArgs e)
        {
            if (this.Collapse != null)
            {
                this.Collapse(this, e);
            }
        }

        public virtual void OnExpand(DNNTreeEventArgs e)
        {
            if (this.Expand != null)
            {
                this.Expand(this, e);
            }
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            this.RegisterDNNVariableControl();
            string expression = "";
            if (!this.IsDownLevel)
            {
                expression = ClientAPI.GetClientVariable(this.Page, this.ClientID + "_xml");
            }
            if (Strings.Len(expression) > 0)
            {
                this.m_objNodes = new TreeNodeCollection(expression, "", this);
            }
        }

        protected override void OnLoad(EventArgs e)
        {
        }

        public virtual void OnNodeClick(DNNTreeNodeClickEventArgs e)
        {
            if (this.NodeClick != null)
            {
                this.NodeClick(this, e);
            }
        }

        public string RaiseClientAPICallbackEvent(string eventArgument)
        {
            string[] strArray = Strings.Split(eventArgument, ClientAPI.COLUMN_DELIMITER, -1, CompareMethod.Binary);
            TreeNodeCollection nodes = new TreeNodeCollection("<root>" + strArray[0] + "</root>", "", this);
            TreeNode node = nodes[0];
            if (node != null)
            {
                if (this.PopulateOnDemand != null)
                {
                    this.PopulateOnDemand(this, new DNNTreeEventArgs(node));
                }
                TreeNode node2 = this.FindNode(node.ID);
                if (node2 != null)
                {
                    return node2.XmlNode.InnerXml;
                }
                return node.XmlNode.InnerXml;
            }
            return null;
        }

        public virtual void RaisePostBackEvent(string eventArgument)
        {
            string[] strArray = Strings.Split(eventArgument, ClientAPI.COLUMN_DELIMITER, -1, CompareMethod.Binary);
            TreeNode node = this.TreeNodes.FindNode(strArray[0]);
            if (node != null)
            {
                if (strArray.Length > 1)
                {
                    string sLeft = strArray[1];
                    if (StringType.StrCmp(sLeft, "Click", false) == 0)
                    {
                        if (!this.CheckBoxes)
                        {
                            foreach (TreeNode node2 in this.TreeNodes.FindSelectedNodes())
                            {
                                node2.Selected = false;
                            }
                        }
                        if (node.ClickAction == eClickAction.Expand)
                        {
                            if (((node.DNNNodes.Count == 0) && this.PopulateNodesFromClient) && (this.PopulateOnDemand != null))
                            {
                                this.PopulateOnDemand(this, new DNNTreeEventArgs(node));
                            }
                            if (node.IsExpanded)
                            {
                                node.Collapse();
                            }
                            else
                            {
                                node.Expand();
                            }
                        }
                        node.Click();
                    }
                    else if (StringType.StrCmp(sLeft, "Checked", false) == 0)
                    {
                        node.Selected = !node.Selected;
                    }
                    else if ((StringType.StrCmp(sLeft, "OnDemand", false) == 0) && (this.PopulateOnDemand != null))
                    {
                        this.PopulateOnDemand(this, new DNNTreeEventArgs(node));
                    }
                }
                else
                {
                    if (node.IsExpanded)
                    {
                        node.Collapse();
                    }
                    else
                    {
                        node.Expand();
                    }
                    if (((node.DNNNodes.Count == 0) && this.PopulateNodesFromClient) && (this.PopulateOnDemand != null))
                    {
                        this.PopulateOnDemand(this, new DNNTreeEventArgs(node));
                    }
                }
            }
        }

        public void RaisePostDataChangedEvent()
        {
        }

        public void RegisterClientScript()
        {
            if (!this.IsDownLevel)
            {
                ClientAPI.RegisterClientReference(this.Page, ClientAPI.ClientNamespaceReferences.dnn_dom);
                ClientAPI.RegisterClientReference(this.Page, ClientAPI.ClientNamespaceReferences.dnn_xml);
                if (this.PopulateNodesFromClient)
                {
                    ClientAPI.RegisterClientReference(this.Page, ClientAPI.ClientNamespaceReferences.dnn_xmlhttp);
                }
                if (!ClientAPI.IsClientScriptBlockRegistered(this.Page, "dnn.controls.dnntree.js"))
                {
                    ClientAPI.RegisterClientScriptBlock(this.Page, "dnn.controls.dnntree.js", "<script src=\"" + this.TreeScriptPath + "dnn.controls.dnntree.js\"></script>");
                }
                ClientAPI.RegisterStartUpScript(this.Page, this.ClientID + "_startup", "<script>dnn.controls.initTree(dnn.dom.getById('" + this.ClientID + "'));</script>");
            }
        }

        public void RegisterDNNVariableControl()
        {
            if (((HtmlInputHidden) DotNetNuke.UI.Utilities.Globals.FindControlRecursive(this.Page, "__dnnVariable")) == null)
            {
                HtmlInputHidden child = new HtmlInputHidden();
                child.ID = "__dnnVariable";
                this.Controls.Add(child);
            }
        }

        protected override void Render(HtmlTextWriter writer)
        {
            IEnumerator enumerator=null;
            this.TreeWriter.RenderTree(writer, this);
            try
            {
                enumerator = this.Controls.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    ((Control) enumerator.Current).RenderControl(writer);
                }
            }
            finally
            {
                if (enumerator is IDisposable)
                {
                    ((IDisposable) enumerator).Dispose();
                }
            }
        }

        protected override object SaveViewState()
        {
            object objectValue = RuntimeHelpers.GetObjectValue(base.SaveViewState());
            object obj3 = RuntimeHelpers.GetObjectValue(((IStateManager) this.ImageList).SaveViewState());
            return new object[] { RuntimeHelpers.GetObjectValue(objectValue), RuntimeHelpers.GetObjectValue(obj3) };
        }

        public TreeNode SelectNode(string strID)
        {
            TreeNode node = null;
            if (this.TreeNodes.Count > 0)
            {
                node = this.FindNode(strID);
                if (node == null)
                {
                    return node;
                }
                node.Selected = true;
                for (TreeNode node3 = node.Parent; node3 != null; node3 = node3.Parent)
                {
                    node3.Expand();
                }
            }
            return node;
        }

        public TreeNode SelectNodeByKey(string strKey)
        {
            TreeNode node = null;
            if (this.TreeNodes.Count > 0)
            {
                node = this.FindNodeByKey(strKey);
                if (node == null)
                {
                    return node;
                }
                node.Selected = true;
                for (TreeNode node3 = node; node3 != null; node3 = node3.Parent)
                {
                    node3.Expand();
                }
            }
            return node;
        }

        protected override void TrackViewState()
        {
            base.TrackViewState();
        }

        private void UpdateNodes(TreeNodeCollection objNodes)
        {
            IEnumerator enumerator=null;
            try
            {
                enumerator = objNodes.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    TreeNode current = (TreeNode) enumerator.Current;
                    if (Strings.Len(current.Image) > 0)
                    {
                        if (!this.ImageList.Contains(current.Image))
                        {
                            current.ImageIndex = this.ImageList.Add(current.Image);
                        }
                        else
                        {
                            current.ImageIndex = this.ImageList.IndexOf(current.Image);
                        }
                        current.Image = null;
                    }
                    if (current.DNNNodes.Count > 0)
                    {
                        this.UpdateNodes(current.TreeNodes);
                    }
                }
            }
            finally
            {
                if (enumerator is IDisposable)
                {
                    ((IDisposable) enumerator).Dispose();
                }
            }
        }

        [PersistenceMode(PersistenceMode.Attribute), Bindable(true)]
        public string CallbackStatusFunction
        {
            get
            {
                return StringType.FromObject(this.ViewState["CallbackStatusFunction"]);
            }
            set
            {
                this.ViewState["CallbackStatusFunction"] = value;
            }
        }

        [DefaultValue(false), PersistenceMode(PersistenceMode.Attribute), Bindable(true)]
        public bool CheckBoxes
        {
            get
            {
                return BooleanType.FromObject(this.ViewState["CheckBoxes"]);
            }
            set
            {
                this.ViewState["CheckBoxes"] = value;
            }
        }

        public string ClientAPIScriptPath
        {
            get
            {
                return ClientAPI.ScriptPath;
            }
            set
            {
                ClientAPI.ScriptPath = value;
            }
        }

        [DefaultValue(""), Bindable(true), PersistenceMode(PersistenceMode.Attribute)]
        public string CollapsedNodeImage
        {
            get
            {
                return StringType.FromObject(this.ViewState["CollapsedNodeImage"]);
            }
            set
            {
                this.ViewState["CollapsedNodeImage"] = value;
            }
        }

        [PersistenceMode(PersistenceMode.Attribute), Bindable(true), DefaultValue("")]
        public string DefaultChildNodeCssClass
        {
            get
            {
                return StringType.FromObject(this.ViewState["DefaultChildNodeCssClass"]);
            }
            set
            {
                this.ViewState["DefaultChildNodeCssClass"] = value;
            }
        }

        [PersistenceMode(PersistenceMode.Attribute), DefaultValue(""), Bindable(true)]
        public string DefaultIconCssClass
        {
            get
            {
                return StringType.FromObject(this.ViewState["DefaultIconCssClass"]);
            }
            set
            {
                this.ViewState["DefaultIconCssClass"] = value;
            }
        }

        [Bindable(true), PersistenceMode(PersistenceMode.Attribute), DefaultValue("")]
        public string DefaultNodeCssClass
        {
            get
            {
                return this.CssClass;
            }
            set
            {
                this.CssClass = value;
            }
        }

        [PersistenceMode(PersistenceMode.Attribute), DefaultValue(""), Bindable(true)]
        public string DefaultNodeCssClassOver
        {
            get
            {
                return StringType.FromObject(this.ViewState["DefaultNodeCssClassOver"]);
            }
            set
            {
                this.ViewState["DefaultNodeCssClassOver"] = value;
            }
        }

        [PersistenceMode(PersistenceMode.Attribute), DefaultValue(""), Bindable(true)]
        public string DefaultNodeCssClassSelected
        {
            get
            {
                return StringType.FromObject(this.ViewState["DefaultNodeCssClassSelected"]);
            }
            set
            {
                this.ViewState["DefaultNodeCssClassSelected"] = value;
            }
        }

        [PersistenceMode(PersistenceMode.Attribute), DefaultValue(""), Bindable(true)]
        public string ExpandedNodeImage
        {
            get
            {
                return StringType.FromObject(this.ViewState["ExpandedNodeImage"]);
            }
            set
            {
                this.ViewState["ExpandedNodeImage"] = value;
            }
        }

        public bool ForceDownLevel
        {
            get
            {
                return BooleanType.FromObject(this.ViewState["ForceDownLevel"]);
            }
            set
            {
                this.ViewState["ForceDownLevel"] = value;
            }
        }

        [PersistenceMode(PersistenceMode.InnerProperty), Browsable(true)]
        public NodeImageCollection ImageList
        {
            get
            {
                if (this.m_objImages == null)
                {
                    this.m_objImages = new NodeImageCollection();
                    if (this.IsTrackingViewState)
                    {
                        ((IStateManager) this.m_objImages).TrackViewState();
                    }
                }
                return this.m_objImages;
            }
        }

        [Bindable(true), DefaultValue(10), PersistenceMode(PersistenceMode.Attribute)]
        public int IndentWidth
        {
            get
            {
                return IntegerType.FromObject(this.ViewState["IndentWidth"]);
            }
            set
            {
                this.ViewState["IndentWidth"] = value;
            }
        }

        [Browsable(false)]
        public bool IsDownLevel
        {
            get
            {
                return ((this.ForceDownLevel || !ClientAPI.BrowserSupportsFunctionality(ClientAPI.ClientFunctionality.DHTML)) || !ClientAPI.BrowserSupportsFunctionality(ClientAPI.ClientFunctionality.XML));
            }
        }

        public string JSFunction
        {
            get
            {
                return StringType.FromObject(this.ViewState["JSFunction"]);
            }
            set
            {
                this.ViewState["JSFunction"] = value;
            }
        }

        [Bindable(false), PersistenceMode(PersistenceMode.Attribute), DefaultValue(true)]
        public bool PopulateNodesFromClient
        {
            get
            {
                return ((this.ViewState["PopNodesFromClient"] == null) || BooleanType.FromObject(this.ViewState["PopNodesFromClient"]));
            }
            set
            {
                this.ViewState["PopNodesFromClient"] = value;
            }
        }

        [Browsable(false)]
        public Collection SelectedTreeNodes
        {
            get
            {
                return this.TreeNodes.FindSelectedNodes();
            }
        }

        [Description("Directory to find the images for the menu.  Need to have spacer.gif here!"), DefaultValue("images/")]
        public string SystemImagesPath
        {
            get
            {
                if (Strings.Len(RuntimeHelpers.GetObjectValue(this.ViewState["SystemImagesPath"])) == 0)
                {
                    return "images/";
                }
                return StringType.FromObject(this.ViewState["SystemImagesPath"]);
            }
            set
            {
                this.ViewState["SystemImagesPath"] = value;
            }
        }

        [Bindable(true), DefaultValue("")]
        public string Target
        {
            get
            {
                return StringType.FromObject(this.ViewState["Target"]);
            }
            set
            {
                this.ViewState["Target"] = value;
            }
        }

        [PersistenceMode(PersistenceMode.InnerProperty), Browsable(true)]
        public TreeNodeCollection TreeNodes
        {
            get
            {
                if (this.m_objNodes == null)
                {
                    this.m_objNodes = new TreeNodeCollection(this.ClientID, this);
                }
                return this.m_objNodes;
            }
        }

        public string TreeScriptPath
        {
            get
            {
                if (Strings.Len(RuntimeHelpers.GetObjectValue(this.ViewState["TreeScriptPath"])) == 0)
                {
                    return this.ClientAPIScriptPath;
                }
                return StringType.FromObject(this.ViewState["TreeScriptPath"]);
            }
            set
            {
                this.ViewState["TreeScriptPath"] = value;
            }
        }

        private IDNNTreeWriter TreeWriter
        {
            get
            {
                if (this.IsDownLevel)
                {
                    return new DNNTreeWriter();
                }
                return new DNNTreeUpLevelWriter();
            }
        }

        [DefaultValue(""), Bindable(true), PersistenceMode(PersistenceMode.Attribute)]
        public string WorkImage
        {
            get
            {
                return StringType.FromObject(this.ViewState["WorkImage"]);
            }
            set
            {
                this.ViewState["WorkImage"] = value;
            }
        }

        public delegate void DNNTreeEventHandler(object source, DNNTreeEventArgs e);

        public delegate void DNNTreeNodeClickHandler(object source, DNNTreeNodeClickEventArgs e);
    }
}

